﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using AForge.Imaging.Filters;

namespace Clustering
{
    public class LedPatternSeparator
    {
        private Kmeans kmeans;
        private Cluster[] lastClusters;
        private int initIterations = 20;
        private int continueIterations = 5;
        private int initRepeats = 5;
        private int continueRepeats = 2;

        //TODO: Laci: extra filterek, hogy B&W legyen
        private Grayscale grayscaleFilter = new Grayscale(0.33, 0.33, 0.33);
        private Threshold thresholdFilter = new Threshold(150);


        public Kmeans Kmeans
        {
            get { return kmeans; }
        }

        public void Reset()
        {
            this.lastClusters = null;
        }

        public LedPatternSeparator(int numberOfPatterns)
        {
            this.kmeans = new Kmeans();
            this.kmeans.NumberOfClusters = numberOfPatterns;
            this.kmeans.Dimension = 2;
        }


        public Bitmap[] FindClusters(Bitmap image)
        {

            this.kmeans.Points = ImageListConverter.BitmapToList(image);
            if (this.lastClusters == null)
            {
                this.lastClusters = this.kmeans.RepeatInitialClustering(this.initRepeats, this.initIterations);
            }
            else
            {
                this.lastClusters = this.kmeans.RepeatContinuationOfClustering(this.continueRepeats, this.continueIterations);
            }

            if (this.lastClusters == null)
                return null;
            Bitmap[] clusterImages = new Bitmap[this.lastClusters.Length];

            for (int i = 0; i < this.lastClusters.Length; i++)
            {
                clusterImages[i] =
                    //TODO: Laci: extra filterek, hogy B&W legyen
                    //                   thresholdFilter.Apply(
                    //                    grayscaleFilter.Apply(
                    ImageListConverter.ListToBitmap(this.lastClusters[i].PointsInCluster, image.Width, image.Height);
                // ));
            }
            return clusterImages;

            //return getClusteredBitmaps(image.Width, image.Height, image);  
        }
        
        public Bitmap[] FindClusters2(Bitmap image)
        {

            this.kmeans.Points = ImageListConverter.BitmapToList(image);
            if (this.lastClusters == null)
            {
                this.lastClusters = this.kmeans.RepeatInitialClustering(this.initRepeats, this.initIterations);
            }
            else
            {
                this.lastClusters = this.kmeans.RepeatContinuationOfClustering(this.continueRepeats, this.continueIterations);
            }

            if (this.lastClusters == null)
                return null;
            Bitmap[] clusterImages = new Bitmap[this.lastClusters.Length];

            //for (int i = 0; i < this.lastClusters.Length; i++)
            //{
            //    clusterImages[i] =
            //        //TODO: Laci: extra filterek, hogy B&W legyen
            //        //                   thresholdFilter.Apply(
            //        //                    grayscaleFilter.Apply(
            //        ImageListConverter.ListToBitmap(this.lastClusters[i].PointsInCluster, image.Width, image.Height);
            //        // ));
            //}
            //return clusterImages;

            return getClusteredBitmaps(image.Width, image.Height, image);



        }

        private Bitmap[] getClusteredBitmaps(int width, int height, Bitmap image)
        {
            double[] center0 = lastClusters[0].CalculateCenter();
            int x0 = (int)center0[0];
            int y0 = (int)center0[1];
            double[] center1 = lastClusters[1].CalculateCenter();
            int x1 = (int)center1[0];
            int y1 = (int)center1[1];
            Bitmap bmp0 = new Bitmap(width, height);
            Bitmap bmp1 = new Bitmap(width, height);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    int dist0 = (x - x0) * (x - x0) + (y - y0) * (y - y0);
                    int dist1 = (x - x1) * (x - x1) + (y - y1) * (y - y1);
                    if (dist0 < dist1)
                        bmp0.SetPixel(x, y, image.GetPixel(x, y));
                    else
                        bmp1.SetPixel(x, y, image.GetPixel(x, y));
                }
            }
            return new Bitmap[] { bmp0, bmp1 };
        }

        public void RotateClusters()
        {
            this.kmeans.RotateClusters();
        }
    }

}
